local Node = {}
Node.__cname = "util.LinkedList.Node"
Node.__index = Node

function Node.new(list, value)
    local obj = {}
    setmetatable(obj, Node)
    obj:ctor(list, value)
    return obj
end

function Node:ctor(list, value)
    self.list = list
    self.value = value
    self.next = nil
    self.prev = nil
    self.ext = nil
end

function Node:SetValue(value)
    self.value = value
end
function Node:GetValue()
    return self.value
end

function Node:GetNext()
    return self.next
end
function Node:GetPrev()
    return self.prev
end


local LinkedList = {}
LinkedList.__cname = "util.LinkedList"
LinkedList.__index = LinkedList

function LinkedList.new()
    local obj = {}
    setmetatable(obj, LinkedList)
    obj:ctor()
    return obj
end

function LinkedList:ctor()
    self:_Reset()
end

function LinkedList:_Reset()
    self.head = nil
    self.tail = nil
    self.count = 0
end

function LinkedList:Clear()
    if self.count < 1 then return end

    local allNodes = {}
    local node = self.head
    while nil ~= node do
        node.list = nil
        node.prev = nil
        local tempNext = node.next
        node.next = nil
        table.insert(allNodes, node)
        node = tempNext
    end
    self:_Reset()
    return allNodes --所有游离状nodes
end

function LinkedList:GetCount()
    return self.count
end

function LinkedList:GetFirst()
    if 0 == self.count then return nil end
    return self.head
end
function LinkedList:GetFirstValue()
    if 0 == self.count then return nil end
    return self.head:GetValue()
end

function LinkedList:GetLast()
    if 0 == self.count then return nil end
    return self.tail
end
function LinkedList:GetLastValue()
    if 0 == self.count then return nil end
    return self.tail:GetValue()
end

function LinkedList:AddFirst(value)
    if 0 == self.count then
        self.count = 1
        self.head = Node.new(self, value)
        self.tail = self.head
        return self.head
    end
    self.count = self.count + 1
    local newHead = Node.new(self, value)
    self:_SetHead(newHead)
    return newHead
end

function LinkedList:AddLast(value)
    if 0 == self.count then
        self.count = 1
        self.head = Node.new(self, value)
        self.tail = self.head
        return self.head
    end
    self.count = self.count + 1
    local newTail = Node.new(self, value)
    self:_SetTail(newTail)
    return newTail
end

function LinkedList:AddBefore(value, beforeNode)
    if beforeNode.list ~= self then return end

    if beforeNode == self.head then
        return self:AddFirst(value)
    end

    local newNode = Node.new(self, value)
    self:_SetBefore(newNode, beforeNode)
end

function LinkedList:AddAfter(value, afterNode)
    if afterNode.list ~= self then return end

    if afterNode == self.tail then
        return self:AddLast(value)
    end

    local newNode = Node.new(self, value)
    self:_SetAfter(newNode, afterNode)
end

function LinkedList:GetIterator()
    local iteratorCur = self.head
    local function iterator(itrObj, node)
        local ret = iteratorCur
        if nil ~= ret then
            iteratorCur = iteratorCur.next
            return ret, ret.value
        end
        return nil
    end
    return iterator
end

function LinkedList:_SetHead(node)
    -- node <=> oldHead建立链接
    node.next = self.head
    self.head.prev = node
    -- 设为新head
    self.head = node
end

---移动到链表头
function LinkedList:MoveToFirst(node)
    if node.list ~= self then return end
    if self.head == node then return end

    if self.tail == node then
        self:_DetachTail()
    else
        self:_DetachNode(node)
    end

    self:_SetHead(node)
end

function LinkedList:_SetTail(node)
    -- oldTail <=> node建立链接
    node.prev = self.tail
    self.tail.next = node
    -- 设为新tail
    self.tail = node
end

function LinkedList:MoveToLast(node)
    if node.list ~= self then return end
    if self.tail == node then return end

    if self.head == node then
        self:_DetachHead()
    else
        self:_DetachNode(node)
    end

    self:_SetTail(node)
end

function LinkedList:_SetBefore(node, beforeNode)
    -- node <=> beforeNode建立链接
    node.next = beforeNode
    local node2Prev = beforeNode.prev
    beforeNode.prev = node
    -- beforeNode.prev <=> node建立链接
    node.prev = node2Prev
    node2Prev.next = node
end

function LinkedList:MoveBefore(node, beforeNode)
    if self.count <= 1 then return end
    if node.list ~= self then return end
    if beforeNode.list ~= self then return end
    if node.next == beforeNode and beforeNode.prev == node then
        print("ignore")
        return
    end

    if self.head == beforeNode then
        self:MoveToFirst(node)
        return
    end

    if self.head == node then
        self:_DetachHead()
    elseif self.tail == node then
        self:_DetachTail()
    else
        self:_DetachNode(node)
    end

    self:_SetBefore(node, beforeNode)
end

function LinkedList:_SetAfter(node, afterNode)
    -- afterNode <=> node建立链接
    node.prev = afterNode
    local node2Next = afterNode.next
    afterNode.next = node
    -- node <=> afterNode.next建立链接
    node.next = node2Next
    node2Next.prev = node
end

function LinkedList:MoveAfter(node, afterNode)
    if self.count <= 1 then return end
    if node.list ~= self then return end
    if afterNode.list ~= self then return end
    if afterNode.next == node and node.prev == afterNode then
        print("ignore")
        return
    end

    if self.tail == afterNode then
        self:MoveToLast(node)
        return
    end

    if self.head == node then
        self:_DetachHead()
    elseif self.tail == node then
        self:_DetachTail()
    else
        self:_DetachNode(node)
    end

    self:_SetAfter(node, afterNode)
end

function LinkedList:_DetachHead()
    local newHead = self.head.next
    newHead.prev = nil --断开旧head
    self.head.next = nil--旧head清除next
    self.head = newHead --设置新head
end

function LinkedList:RemoveFirst()
    if 0 == self.count then return nil end

    local ret = self.head
    if 1 == self.count then
        self:_Reset()
    else
        self:_DetachHead()
        self.count = self.count - 1
    end
    ret.list = nil
    return ret
end

function LinkedList:_DetachTail()
    local newTail = self.tail.prev
    newTail.next = nil --断开旧tail
    self.tail.prev = nil --旧tail清除prev
    self.tail = newTail --设置新tail
end

---移除链表尾
function LinkedList:RemoveLast()
    if 0 == self.count then return nil end

    local ret = self.tail
    if 1 == self.count then
        self:_Reset()
    else
        self:_DetachTail()
        self.count = self.count - 1
    end
    ret.list = nil
    return ret
end

function LinkedList:_DetachNode(node)
    node.prev.next = node.next
    node.next.prev = node.prev
    node.prev = nil
    node.next = nil
end

function LinkedList:Remove(node)
    if node.list ~= self then return end

    if self.head == node then
        self:RemoveFirst()
    elseif self.tail == node then
        self:RemoveLast()
    else
        self:_DetachNode(node)
        self.count = self.count - 1
        node.list = nil
    end
end

function LinkedList:__tostring()
    if 0 == self.count then return "" end

    local strTb = {}
    local node = self.head
    while nil ~= node do
        if nil == node.value then
            table.insert(strTb, "nil")
        else
            table.insert(strTb, tostring(node.value))
        end
        node = node.next
    end
    return table.concat(strTb, ",")
end

return LinkedList
